import { CheckCircleOutlined, MinusCircleOutlined } from '@ant-design/icons';
import {
  ProFieldFC,
  ProFieldRequestData,
  RequestOptionsType,
} from '@ant-design/pro-components';
import { nanoid } from '@ant-design/pro-utils';
import { AutoComplete, AutoCompleteProps, ConfigProvider, Input } from 'antd';
import { DefaultOptionType } from 'antd/es/select';
import classNames from 'classnames';
import React, {
  useContext,
  useEffect,
  useImperativeHandle,
  useRef,
  useState,
} from 'react';

export type SfwAutoCompleteProps = Omit<AutoCompleteProps, 'onChange'> & {
  text: string;
  bordered?: boolean;
  /** 防抖动时间 默认10 单位ms */
  debounceTime?: number;
  /** 从服务器读取选项 */
  request?: ProFieldRequestData;
  /** 重新触发的时机 */
  params?: any;
  /**
   * 是否在输入框聚焦时触发搜索
   *
   * @default false
   */
  searchOnFocus?: boolean;
  /**
   * 选择完一个之后是否清空搜索项重新搜索
   *
   * @default false
   */
  resetAfterSelect?: boolean;
  /** 刷新数据 */
  fetchData: (keyWord?: string) => void;

  /** 清空数据 */
  resetData: () => void;

  /**
   * 当搜索关键词发生变化时是否请求远程数据
   *
   * @default true
   */
  fetchDataOnSearch?: boolean;
  /** 自定义选项渲染 */
  optionItemRender?: (item: any) => React.ReactNode;
  onChange?: (value: RequestOptionsType) => void;
};

const SfwAutoComplete: ProFieldFC<SfwAutoCompleteProps> = (props, ref) => {
  const {
    optionItemRender,
    onSearch,
    onFocus,
    value,
    onChange,
    autoClearSearchValue = true,
    searchOnFocus = false,
    resetAfterSelect = false,
    fetchDataOnSearch = true,
    className,
    disabled,
    options,
    fetchData,
    resetData,
    prefixCls: customizePrefixCls,
    onClear,
    searchValue: propsSearchValue,
    showSearch = true,
    fieldNames,
    ...restProps
  } = props;

  const {
    label: labelPropsName = 'label',
    value: valuePropsName = 'label',
    options: optionsPropsName = 'options',
  } = fieldNames || {};

  const [searchValue, setSearchValue] = useState(propsSearchValue);

  const { getPrefixCls } = useContext(ConfigProvider.ConfigContext);

  const prefixCls = getPrefixCls('pro-filed-search-select', customizePrefixCls);

  // 兼容 renderXXX API。

  const classString = classNames(prefixCls, className, {
    [`${prefixCls}-disabled`]: disabled,
  });

  const selectRef = useRef<any>();

  useImperativeHandle(ref, () => selectRef.current);

  useEffect(() => {
    if (restProps.autoFocus) {
      selectRef?.current?.focus();
    }
  }, [restProps.autoFocus]);

  useEffect(() => {
    setSearchValue(propsSearchValue);
  }, [propsSearchValue]);

  const genOptions = (
    mapOptions: RequestOptionsType[],
  ): DefaultOptionType[] => {
    return mapOptions.map((item, index) => {
      const { optionType, ...resetItem } = item as RequestOptionsType;

      const label = item[labelPropsName];
      const value = item[valuePropsName];
      const itemOptions = item[optionsPropsName] ?? [];

      if (optionType === 'optGroup' || item.options) {
        return {
          label: label,
          ...resetItem,
          data_title: label,
          title: label,
          key: `${label?.toString()}-${index}-${nanoid()}`, // 防止因key相同导致虚拟滚动出问题
          children: genOptions(itemOptions),
        } as DefaultOptionType;
      }

      return {
        title: label,
        ...resetItem,
        data_title: label,
        value: value ?? index,
        key: `${label?.toString()}-${index}-${nanoid()}`,
        'data-item': item,
        label: optionItemRender?.(item as any) || label,
      } as DefaultOptionType;
    });
  };

  return (
    <AutoComplete
      ref={selectRef}
      className={classString}
      disabled={disabled}
      onClear={() => {
        onClear?.();
        fetchData(undefined);
        if (showSearch) {
          setSearchValue(undefined);
        }
      }}
      {...restProps}
      filterOption={
        restProps.filterOption === false
          ? false
          : (inputValue, option) => {
              if (
                restProps.filterOption &&
                typeof restProps.filterOption === 'function'
              ) {
                return restProps.filterOption(inputValue, {
                  ...option,
                  label: option?.data_title,
                });
              }
              return !!(
                option?.data_title
                  ?.toString()
                  .toLowerCase()
                  .includes(inputValue.toLowerCase()) ||
                option?.label
                  ?.toString()
                  .toLowerCase()
                  .includes(inputValue.toLowerCase()) ||
                option?.value
                  ?.toString()
                  .toLowerCase()
                  .includes(inputValue.toLowerCase())
              );
            }
      } // 这里使用pro-components的过滤逻辑
      value={value?.value}
      onSearch={
        showSearch
          ? (value) => {
              if (fetchDataOnSearch) {
                fetchData(value);
              }
              onSearch?.(value);
              setSearchValue(value);
              onChange?.({ value });
            }
          : undefined
      }
      onChange={(value, option) => {
        // 将搜索框置空 和 antd 行为保持一致
        if (showSearch && autoClearSearchValue) {
          fetchData(undefined);
          onSearch?.('');
          setSearchValue(undefined);
        }

        onChange?.(option as RequestOptionsType);

        // 将搜索结果置空，重新搜索
        if (resetAfterSelect) resetData();
      }}
      onFocus={(e) => {
        if (searchOnFocus) {
          fetchData(searchValue);
        }
        onFocus?.(e);
      }}
      options={genOptions((options || []) as RequestOptionsType[])}
    >
      <Input
        addonAfter={
          value?.id ? <CheckCircleOutlined /> : <MinusCircleOutlined />
        }
      />
    </AutoComplete>
  );
};

export default React.forwardRef(SfwAutoComplete);
